#pragma once
/*--------------------------------------------------------------------------------
 * Adaptive Intelligence - Foundation Framework Class Library
 * Version 2.00
 * 
 * Signaled Object Event Class
 *      Provides a wrapper for the C++ event system using signaled objects.
 *------------------------------------------------------------------------------*/

/*--------------------------------------------------------------------------------
 * System Imports
 *------------------------------------------------------------------------------*/
#include "stdafx.h"
using namespace System;
using namespace System::Threading;

namespace Adaptive
{
	namespace Foundation
	{
		/// <summary>
		/// Provides a wrapper for the C++ event system using signaled objects.
		/// </summary>
		/// <remarks>
		/// This class provides a wrapper for using the base CreateEvent() and
		/// WaitForSingleObject() methods used in C++ signaled object events.
		/// </remarks>
		public ref class SignaledObjectEvent : public AiObjectBase
		{
		public:
			/*--------------------------------------------------------------------------------
			 * Public Event Definitions
			 *------------------------------------------------------------------------------*/
			#pragma region Public Event Definitions
			/// <summary>
			/// Occurs when the event object is signaled.
			/// </summary>
			event EventHandler^ EventOccurred;
			#pragma endregion

			/*--------------------------------------------------------------------------------
			 * Constructor / Dispose / Destructor Methods
			 *------------------------------------------------------------------------------*/
			#pragma region Constructor / Dispose / Destructor Methods
			/// <summary>
			/// Initializes a new instance of the class.
			/// </summary>
			/// <remarks>
			/// This is the default constructor.
			/// </remarks>
			SignaledObjectEvent();
			/// <summary>
			/// Initializes a new instance of the class.
			/// </summary>
			/// <param name="eventName">A name to assigned to the signaled object.</param>
			SignaledObjectEvent(String^ eventName);
			/// <summary>
			/// Deallocates internal unmanaged data.
			/// </summary>
			!SignaledObjectEvent();
			/// <summary>
			/// Deallocates internal unmanaged data.
			/// </summary>
			~SignaledObjectEvent();
			#pragma endregion

			/*--------------------------------------------------------------------------------
			 * Public Properties
			 *------------------------------------------------------------------------------*/
			#pragma region Public Properties
			/// <summary>
			/// Gets the handle to the underlying event.
			/// invoked.
			/// </summary>
			/// <value>
			/// An <see cref="IntPtr"/> value containing the event handle, if present;
			/// otherwise, <b>IntPtr.Zero</b>.
			/// </value>
			property IntPtr EventHandle { IntPtr get(); }
			/// <summary>
			/// Gets a value indicating whether the internal <b>WaitForSingleObject</b> method has been
			/// invoked.
			/// </summary>
			/// <value>
			/// <b>true</b> if the <b>WaitForSingleObject()</b> method has already been called on the
			/// instance; otherwise, <b>false</b>.
			/// </value>
			property bool IsWaiting { bool get(); }
			#pragma endregion

			/*--------------------------------------------------------------------------------
	         * Public Methods / Functions
		     *------------------------------------------------------------------------------*/
			#pragma region Public Methods / Functions
			/// <summary>
			/// 
			/// </summary>
			void AsyncWait();
			/// <summary>
			/// 
			/// </summary>
			void virtual Clear() override;
			/// <summary>
			/// 
			/// </summary>
			void ResetEventStatus();
			/// <summary>
			/// 
			/// </summary>
			void SignalEvent();
			/// <summary>
			/// 
			/// </summary>
			void WaitForEvent();
			/// <summary>
			/// 
			/// </summary>
			void WaitForEvent(int milliseconds);

			static void Sleep(int milliseconds);
			#pragma endregion

		protected:
			/*--------------------------------------------------------------------------------
			 * Protected Methods / Event Methods
			 *------------------------------------------------------------------------------*/
			#pragma region Protected Methods / Event Methods
			/// <summary>
			/// Raises the <see cref="Clearing"/> event.
			/// </summary>
			/// <param name="e">
			/// An <see cref="EventArgs"/> event arguments instance.
			/// </param>
			virtual void OnEventOccurred(EventArgs^ e);
			/// <summary>
			/// Determines whether the asynchronous event is ready to be fired.
			/// </summary>
			virtual bool IsEventReady();
			#pragma endregion

		private:
			HANDLE		_eventHandle;
			Thread^		_asyncWaitThread;
			bool		_executeThread;
			void		RunAsyncWaitThread();
			void		StopThread();
		};
	}
}
